// utils/fileHash.js
import CryptoJS from 'crypto-js';

class Md5File {
	// 计算文件hash - 修复版本
	static calculateFileHash(fileInfo, CHUNK_SIZE) {
		return new Promise((resolve, reject) => {
			// #ifdef H5
			// H5环境 - 使用FileReader读取文件
			this.calculateFileHashH5(fileInfo, CHUNK_SIZE).then(resolve).catch(reject);
			// #endif

			// #ifndef H5
			// 小程序环境
			this.calculateFileHashMiniProgram(fileInfo, CHUNK_SIZE).then(resolve).catch(reject);
			// #endif
		});
	}
	// H5环境计算文件hash
	static calculateFileHashH5(fileInfo, CHUNK_SIZE) {
		return new Promise((resolve, reject) => {
			fetch(fileInfo.url)
				.then(response => response.blob())
				.then(blob => {
					const chunkSize = CHUNK_SIZE;
					const chunks = Math.ceil(blob.size / chunkSize);
					let currentChunk = 0;
					// 创建MD5对象
					const md5 = CryptoJS.algo.MD5.create();
					const fileReader = new FileReader();

					fileReader.onload = function(e) {
						try {
							const arrayBuffer = e.target.result;
							const wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(
								arrayBuffer));

							// 直接更新MD5，不单独计算每个分片的哈希
							md5.update(wordArray);

							currentChunk++;

							if (currentChunk < chunks) {
								loadNext();
							} else {
								// 最终计算整个文件的哈希
								const hash = md5.finalize().toString();
								resolve(hash);
							}
						} catch (error) {
							reject(error);
						}
					};

					fileReader.onerror = reject;

					function loadNext() {
						const start = currentChunk * chunkSize;
						const end = Math.min(start + chunkSize, blob.size);
						fileReader.readAsArrayBuffer(blob.slice(start, end));
					}

					loadNext();
				})
				.catch(reject);
		});
	}
	// 小程序环境计算文件hash
	static calculateFileHashMiniProgram(fileInfo, CHUNK_SIZE) {
		return new Promise((resolve, reject) => {
			const fs = uni.getFileSystemManager();
			const fileSize = fileInfo.size;
			const chunkSize = CHUNK_SIZE; // 1MB 分片读取
			let currentPosition = 0;
			let md5 = CryptoJS.algo.MD5.create();

			const readNextChunk = () => {
				if (currentPosition >= fileSize) {
					const hash = md5.finalize().toString();
					resolve(hash);
					return;
				}

				const length = Math.min(chunkSize, fileSize - currentPosition);

				fs.readFile({
					filePath: fileInfo.url,
					position: currentPosition,
					length: length,
					success: (res) => {
						try {
							const wordArray = CryptoJS.lib.WordArray.create(res.data);
							md5.update(wordArray);
							currentPosition += length;
							readNextChunk();
						} catch (error) {
							reject(error);
						}
					},
					fail: (err) => {
						console.error('读取文件失败:', err);
						// 如果读取失败，生成一个基于文件信息的简单hash
						const fallbackHash = CryptoJS.MD5(fileInfo.name + fileInfo.size +
							Date.now()).toString();
						resolve(fallbackHash);
					}
				});
			};

			readNextChunk();
		});
	}
}

export default Md5File;